package org.example.domain.service;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.example.domain.model.factory.LoginTypeStrategeFactory;
import org.example.domain.model.repository.LoginTypeStrategeRepository;
import org.example.domain.system.model.LoginUser;
import org.example.domain.system.model.UserAccount;
import org.example.domain.system.model.req.UserLoginReq;
import org.example.infrastructure.repository.RemoteUserAccountRepository;
import org.example.web.exception.ServerException;
import org.example.web.result.BaseErrorCode;
import org.example.web.result.BaseSuccessCode;
import org.example.web.result.ResultInfo;
import org.springframework.stereotype.Service;

import java.util.Map;
import java.util.Optional;

@Service
@RequiredArgsConstructor
@Slf4j
public class LoginDomainService {
    private final RemoteUserAccountRepository remoteUserAccountRepository;
    private final LoginTypeStrategeFactory loginTypeStrategeFactory;
    public ResultInfo login(UserLoginReq userLoginReq) {
        //查询用户信息
        Optional<ResultInfo<UserAccount>> optional = remoteUserAccountRepository.getUserByUserName(userLoginReq.getUserName());
        if (!optional.isPresent()) {
            throw new ServerException(BaseErrorCode.SERVICE_TIMEOUT_ERROR);
        }
        ResultInfo<UserAccount> resultInfo = optional.get();
        if (!BaseSuccessCode.SUCCESSFUL_OPERATION.code().equals(resultInfo.getStatus())) {
            throw new ServerException(resultInfo.getMessage());
        }
        UserAccount userAccount = resultInfo.getData();
        LoginTypeStrategeRepository loginTypeStrategeRepository = loginTypeStrategeFactory.getLoginTypeStrategeRepository(userLoginReq.getLoginType());
        loginTypeStrategeRepository.loginVerify(userLoginReq, userAccount);
        LoginUser loginUser = LoginUser.builder()
                .userId(userAccount.getUserId())
                .userName(userAccount.getUserName())
                .build();
        Map<String, Object> token = loginTypeStrategeRepository.authentication(loginUser);
        return ResultInfo.success(token);

    }

    public ResultInfo logout(String token, String loginType) {
        LoginTypeStrategeRepository loginTypeStrategeRepository = loginTypeStrategeFactory.getLoginTypeStrategeRepository(loginType);
        loginTypeStrategeRepository.logoutByTokenCache(token);
        return ResultInfo.success();
    }

    public ResultInfo refresh(String token, String loginType) {
        LoginTypeStrategeRepository loginTypeStrategeRepository = loginTypeStrategeFactory.getLoginTypeStrategeRepository(loginType);
        LoginUser loginUser = loginTypeStrategeRepository.getLoginUser(token);
        loginTypeStrategeRepository.verifyLoginUserExpire(loginUser);
        return ResultInfo.success();
    }
}
